﻿////P3367 【模板】并查集
//
//#include <iostream>
//using namespace std;
//
//const int N = 2e5 + 10;
//
//int fa[N] = { 0 };
//
//int n, m;
//
////找
//int find(int x)
//{
//	if (fa[x] == x)
//	{
//		return x;
//	}
//
//	return fa[x] = find(fa[x]);
//}
//
////合并
//void un(int x, int y)
//{
//	int fx = find(x);
//	int fy = find(y);
//	fa[fx] = fy;
//}
//
////判断是不是在一个集合里面
//bool issame(int x, int y)
//{
//	return find(x) == find(y);
//}
//
//int main()
//{
//	cin >> n >> m;
//	
//	//初始化
//	for (int i = 1; i < +n; i++)
//	{
//		fa[i] = i;
//	}
//
//	while (m--)
//	{
//		int z, x, y;
//		cin >> z >> x >> y;
//		if (z == 1)
//		{
//			un(x, y);
//		}
//		else
//		{
//			if (issame(x, y))
//			{
//				cout << "Y" << endl;
//			}
//			else
//			{
//				cout << "N" << endl;
//			}
//		}
//	}
//
//	return 0;
//}



////P1551 亲戚
//
//#include <iostream>
//using namespace std;
//
//const int N = 5010;
//
//int fa[N] = { 0 };
//
//int n, m, p;
//
//int find(int x)
//{
//	if (fa[x] == x)
//	{
//		return x;
//	}
//	
//	return fa[x] = find(fa[x]);
//}
//
//int main()
//{
//	cin >> n >> m >> p;
//
//	//初始化
//	for (int i = 1; i <= n; i++)
//	{
//		fa[i] = i;
//	}
//
//	int x, y;
//	while (m--)
//	{
//		cin >> x >> y;
//		int fx = find(x);
//		int fy = find(y);
//		fa[fx] = fy;
//	}
//
//	while (p--)
//	{
//		cin >> x >> y;
//		if (find(x) == find(y))
//		{
//			cout << "Yes" << endl;
//		}
//		else
//		{
//			cout << "No" << endl;
//		}
//	}
//
//	return 0;
//}


//#include <iostream>
//using namespace std;
//
//const int N = 110;
//
//int dx[] = { 0, 1, 1, 1 };
//int dy[] = { 1, 1, 0, -1 };
//
//char a[N][N];
//int fa[N * N] = { 0 };
//
//int n, m;
//
//int find(int x)
//{
//	if (fa[x] == x)
//	{
//		return x;
//	}
//
//	return fa[x] = find(fa[x]);
//}
//
//void un(int x, int y)
//{
//	int fx = find(x);
//	int fy = find(y);
//	fa[fx] = fy;
//}
//
//int main()
//{
//	cin >> n >> m;
//	for (int i = 0; i < n; i++)
//	{
//		for (int j = 0; j < m; j++)
//		{
//			cin >> a[i][j];
//		}
//	}
//
//	//初始化
//	for (int i = 0; i < n * m; i++)
//	{
//		fa[i] = i;
//	}
//
//	for (int i = 0; i < n; i++)
//	{
//		for (int j = 0; j < m; j++)
//		{
//			if (a[i][j] == 'W')
//			{
//				for (int k = 0; k < 4; k++)
//				{
//					int x = i + dx[k];
//					int y = j + dy[k];
//					if (y >= 0 && a[x][y] == 'W')
//					{
//						un(i * m + j, x * m + y);
//					}
//				}
//			}
//		}
//	}
//
//	int ret = 0;
//	for (int i = 0; i < m * n; i++)
//	{
//		int x = i / m;
//		int y = i % m;
//		if (a[x][y] == 'W' && fa[i] == i)
//		{
//			ret++;
//		}
//	}
//
//	cout << ret << endl;
//	return 0;
//}



#include <iostream>
#include <unordered_map>
#include <algorithm>
using namespace std;

const int N = 1e5 + 10;

struct node
{
	int x; 
	int y;
	int e;
}a[N];

// 离散化 
int pos;
int disc[N * 2];
unordered_map<int, int> mp;

int fa[N * 2];

int n;

// 并查集 
int find(int x)
{
	return fa[x] == x ? x : fa[x] = find(fa[x]);
}

void un(int x, int y)
{
	fa[find(x)] = find(y);
}

bool issame(int x, int y)
{
	return find(x) == find(y);
}

bool solve()
{
	cin >> n;
	// 清空数据 
	pos = 0;
	mp.clear();

	for (int i = 1; i <= n; i++)
	{
		cin >> a[i].x >> a[i].y >> a[i].e;
		disc[++pos] = a[i].x; disc[++pos] = a[i].y;
	}

	// 离散化 
	sort(disc + 1, disc + 1 + pos);
	int cnt = 0;
	for (int i = 1; i <= pos; i++)
	{
		int x = disc[i];
		if (mp.count(x)) 
		{
			continue;
		}
		cnt++;
		mp[x] = cnt;
	}

	// 初始化 
	for (int i = 1; i <= cnt; i++) 
	{
		fa[i] = i;
	}

	// 1. 把所有相等的信息，⽤并查集维护起来 
	for (int i = 1; i <= n; i++)
	{
		int x = a[i].x;
		int y = a[i].y; 
		int e = a[i].e;
		if (e == 1)
		{
			un(mp[x], mp[y]);
		}
	}

	// 2. 拿出不等的信息，判断是否合法 
	for (int i = 1; i <= n; i++)
	{
		int x = a[i].x;
		int y = a[i].y;
		int e = a[i].e;
		if (e == 0)
		{
			if (issame(mp[x], mp[y])) 
			{
				return false;
			}
		}
	}
	return true;
}

int main()
{
	int T; 
	cin >> T;
	while (T--)
	{
		if (solve())
		{
			cout << "YES" << endl;
		}
		else
		{
			cout << "NO" << endl;
		}
	}

	return 0;
}